import argparse
import re
import glob

def parseArgs(argv):
    invocation = argparse.ArgumentParser(prog="golomb")
    invocation.add_argument("paths", nargs="+", metavar="PATHS",
               help="files to encode/decode")
    group1 = invocation.add_mutually_exclusive_group()
    group1.add_argument("-d", action="store_true", dest=
               "decode", help="decode files")
    invocation.add_argument("-w", dest="wordSize",
               default="8", help="size of a raw data word in bits; "
               "format: n[[-n],...]")
    invocation.add_argument("-m", dest="M", default="0",
               help="M parameter (0 for adaptive mode); " "format: n[[-n],...]")
    invocation.add_argument("-v", action="store_true", dest=
              "verbose", help="verbose mode")
    invocation.add_argument("-D", action="store_true", dest=
              "debug", help="debug mode")
    group2 = invocation.add_mutually_exclusive_group()
    group2.add_argument("-s", action="store", dest=
              "suffix", help="specify suffix for output files")
    group2.add_argument("--stdout", action="store_true", dest=
              "stdout", help="output to stdout")
    group1.add_argument("-b", "--benchmark", action="store_true", dest=
              "benchmark", help="conduct benchmark")
    invocation.add_argument("-a", "--assert", action="store_true", dest=
              "asserting", help="assert proper encoding/decoding")
    
    args = invocation.parse_args(argv[1:])
    
    reRange = r'^\d+(-\d+)?(,\d+(-\d+)?)*$'
    if re.match(reRange, args.wordSize) is None:
        invocation.error("ivalid format for WORDSIZE; must match regex " + reRange)
    if re.match(reRange, args.M) is None:
        invocation.error("ivalid format for M; must match regex " + reRange)
    
    args.wordSize = range2List(args.wordSize)
    args.M = range2List(args.M)
        
    if min(args.wordSize) < 1 or max(args.wordSize) > 24:
        invocation.error("WORDSIZE must be an integer in range [1, 24]")
    if min(args.M) < 0 or min(args.M) > 2 ** 32:
        invocation.error("M must be and integer in range [0, 2^32]")    
    
    
    args.inPaths = []
    args.outPaths = []
    
    
    i = 0    
    for path in args.paths:
        args.inPaths += glob.glob(path)
    if not args.stdout:
        for path in args.inPaths:
            args.outPaths.append(standardPath(path, args.decode, args.suffix, 
                                              args.stdout))
    
    return args
        
def standardPath(path, decode, suffix, stdout):
    if stdout:
        return None
    if not decode:
        if suffix is None:
            return path + ".gol"
        else:
            return path + suffix
    else:
        if suffix is None:
            if path[-4:] == ".gol":
                return path[:-4]
            else:
                return path + ".decoded"
        else:
            if path[-4:] == ".gol":
                return path[:-4] + suffix 
            else:
                return path + suffix
        
def range2List(R):
    R = R.split(",")
    A = set()
    for i in R:
        r = i.split("-")
        if len(r) == 2:
            A |= set(range(int(r[0]), int(r[1]) + 1))
        else:
            A.add(int(r[0]))
    L = list(A)
    L.sort()
    return L
